﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using InterfazGrafico.LibreriaClases.Clases;
using InterfazGrafico.LibreriaConstantes;
using InterfazGrafico.LibreriaConstantes.Elementos;

namespace InterfazGrafico.LibreriaClases.Propiedades
{
    /// <summary>
    /// Almacena las propiedades de un elemento específico.
    /// </summary>
    public class PActualizarDatos : Propiedades
    {
        /// <summary>
        /// Entrada de datos.
        /// </summary>
        public string Entrada
        {
            get
            {
                return this.getPropiedadString(CActualizarDatos.Entrada);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.Entrada, value);
            }
        }

        /// <summary>
        /// Salida de datos.
        /// </summary>
        public string Salida
        {
            get
            {
                return this.getPropiedadString(CActualizarDatos.Salida);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.Salida, value);
            }
        }

        /// <summary>
        /// Estructura de entrada.
        /// </summary>
        public string EstructuraEntrada
        {
            get
            {
                return this.getPropiedadString(CActualizarDatos.EstructuraEntrada);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.EstructuraEntrada, value);
            }
        }

        /// <summary>
        /// Estructura de salida.
        /// </summary>
        public string EstructuraSalida
        {
            get
            {
                return this.getPropiedadString(CActualizarDatos.EstructuraSalida);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.EstructuraSalida, value);
            }
        }

        /// <summary>
        /// Lista de tablas
        /// </summary>
        public List<string> ListaTablasDatos
        {
            get
            {
                return this.getPropiedadListaString(CActualizarDatos.ListaTablasDatos);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.ListaTablasDatos, value);
            }
        }

        /// <summary>
        /// Lista de estructuras de las tablas
        /// </summary>
        public List<string> ListaTablasEstructuras
        {
            get
            {
                return this.getPropiedadListaString(CActualizarDatos.ListaTablasEstructuras);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.ListaTablasEstructuras, value);
            }
        }

        /// <summary>
        /// Lista de campos clave de cada tabla
        /// </summary>
        public List<List<string>> ListaTablasCamposClaveTabla
        {
            get
            {
                return this.getPropiedadListaListaString(CActualizarDatos.ListaTablasCamposClaveTablas);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.ListaTablasCamposClaveTablas, value);
            }
        }

        /// <summary>
        /// Lista de campos clave del maestro para cada tabla
        /// </summary>
        public List<List<string>> ListaTablasCamposClaveMaestro
        {
            get
            {
                return this.getPropiedadListaListaString(CActualizarDatos.ListaTablasCamposClaveMaestro);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.ListaTablasCamposClaveMaestro, value);
            }
        }

        /// <summary>
        /// Lista de campos fuente de cada tabla
        /// </summary>
        public List<List<string>> ListaTablasCamposFuenteTabla
        {
            get
            {
                return this.getPropiedadListaListaString(CActualizarDatos.ListaTablasCamposFuenteTablas);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.ListaTablasCamposFuenteTablas, value);
            }
        }

        /// <summary>
        /// Lista de campos destino del maestro para cada tabla
        /// </summary>
        public List<List<string>> ListaTablasCamposDestinoMaestro
        {
            get
            {
                return this.getPropiedadListaListaString(CActualizarDatos.NodoTablasCamposDestinoMaestro);
            }
            set
            {
                this.setOrAddPropiedad(CActualizarDatos.NodoTablasCamposDestinoMaestro, value);
            }
        }


        /// <summary>
        /// Constructor por defecto.
        /// </summary>
        public PActualizarDatos()
            : base()
        {
        }

        /// <summary>
        /// Obtiene los parámetros a partir del fichero XML indicado.
        /// </summary>
        /// <param name="fichero">Fichero de configuración XML</param>
        override public void leer(string fichero)
        {
            try
            {
                base.leer(fichero);
                XmlDocument xml = LeerXml.AbrirFicheroParametros(fichero);

                try
                { this.Entrada = LeerXml.ObtenerValorCampo(xml, CActualizarDatos.RutaEntrada); }
                catch (Exception)
                { this.Entrada = string.Empty; }

                try
                { this.Salida = LeerXml.ObtenerValorCampo(xml, CActualizarDatos.RutaSalida); }
                catch (Exception)
                { this.Salida = string.Empty; }

                try
                { this.EstructuraEntrada = LeerXml.ObtenerValorCampo(xml, CActualizarDatos.RutaEstructuraEntrada); }
                catch (Exception)
                { this.EstructuraEntrada = string.Empty; }

                try
                { this.EstructuraSalida = LeerXml.ObtenerValorCampo(xml, CActualizarDatos.RutaEstructuraSalida); }
                catch (Exception)
                { this.EstructuraSalida = string.Empty; }

                try
                {
                    int numeroTablas = LeerXml.ObtenerNumeroNodosCampo(xml, CActualizarDatos.RutaTablas);
                    List<string> listaTablasDatos = new List<string>();
                    List<string> listaTablasEstructuras = new List<string>();
                    List<List<string>> listaTablasCamposClaveTabla = new List<List<string>>();
                    List<List<string>> listaTablasCamposClaveMaestro = new List<List<string>>();
                    List<List<string>> listaTablasCamposFuenteTabla = new List<List<string>>();
                    List<List<string>> listaTablasCamposDestinoMaestro = new List<List<string>>();
                    
                    // Por cada tabla obtiene
                    for (int indiceTabla = 0; indiceTabla < numeroTablas; indiceTabla++)
                    {
                        // Fichero de datos
                        try
                        { listaTablasDatos.Add(LeerXml.ObtenerValorCampo(xml, CActualizarDatos.RutaTablas, indiceTabla, Constantes.NodoXMLActual + CActualizarDatos.NodoTablasDatos)); }
                        catch (Exception)
                        { continue; }

                        // Fichero de estructuras
                        string estructuraTabla = string.Empty;
                        try
                        { estructuraTabla = LeerXml.ObtenerValorCampo(xml, CActualizarDatos.RutaTablas, indiceTabla, Constantes.NodoXMLActual + CActualizarDatos.NodoTablasEstructuras); }
                        catch (Exception)
                        { estructuraTabla = string.Empty; }
                        listaTablasEstructuras.Add(estructuraTabla);

                        // Campos clave de la tabla
                        List<string> camposClaveTabla;
                        try
                        { camposClaveTabla = LeerXml.ObtenerListadoValorCampo(xml, CActualizarDatos.RutaTablas, CActualizarDatos.SeparadorListado, indiceTabla, CActualizarDatos.NodoTablasCamposClaveTabla); }
                        catch (Exception)
                        { camposClaveTabla = new List<string>(); }
                        listaTablasCamposClaveTabla.Add(camposClaveTabla);

                        // Campos clave de la entrada
                        List<string> camposClaveMaestro;
                        try
                        { camposClaveMaestro = LeerXml.ObtenerListadoValorCampo(xml, CActualizarDatos.RutaTablas, CActualizarDatos.SeparadorListado, indiceTabla, CActualizarDatos.NodoTablasCamposClaveMaestro); }
                        catch (Exception)
                        { camposClaveMaestro = new List<string>(); }
                        listaTablasCamposClaveMaestro.Add(camposClaveMaestro);

                        // Campos fuente de la tabla
                        List<string> camposFuenteTabla;
                        try
                        { camposFuenteTabla = LeerXml.ObtenerListadoValorCampo(xml, CActualizarDatos.RutaTablas, CActualizarDatos.SeparadorListado, indiceTabla, CActualizarDatos.NodoTablasCamposFuenteTabla); }
                        catch (Exception)
                        { camposFuenteTabla = new List<string>(); }
                        listaTablasCamposFuenteTabla.Add(camposFuenteTabla);

                        // Campos destino de la entrada
                        List<string> camposDestinoMaestro;
                        try
                        { camposDestinoMaestro = LeerXml.ObtenerListadoValorCampo(xml, CActualizarDatos.RutaTablas, CActualizarDatos.SeparadorListado, indiceTabla, CActualizarDatos.NodoTablasCamposDestinoMaestro); }
                        catch (Exception)
                        { camposDestinoMaestro = new List<string>(); }
                        listaTablasCamposDestinoMaestro.Add(camposDestinoMaestro);

                        // Comprobación listado campos
                        if (camposClaveTabla.Count != camposClaveMaestro.Count)
                        {
                            camposClaveMaestro = new List<string>();
                            camposClaveTabla = new List<string>();
                        }
                        if (camposFuenteTabla.Count != camposDestinoMaestro.Count)
                        {
                            camposFuenteTabla = new List<string>();
                            camposDestinoMaestro = new List<string>();
                        }
                    }
                    
                    this.ListaTablasDatos = listaTablasDatos;
                    this.ListaTablasEstructuras = listaTablasEstructuras;
                    this.ListaTablasCamposClaveTabla = listaTablasCamposClaveTabla;
                    this.ListaTablasCamposClaveMaestro = listaTablasCamposClaveMaestro;
                    this.ListaTablasCamposFuenteTabla = listaTablasCamposFuenteTabla;
                    this.ListaTablasCamposDestinoMaestro = listaTablasCamposDestinoMaestro;
                }
                catch (Exception)
                {
                    this.ListaTablasDatos = new List<string>();
                    this.ListaTablasEstructuras = new List<string>();
                    this.ListaTablasCamposClaveTabla = new List<List<string>>();
                    this.ListaTablasCamposClaveMaestro = new List<List<string>>();
                    this.ListaTablasCamposFuenteTabla = new List<List<string>>();
                    this.ListaTablasCamposDestinoMaestro = new List<List<string>>();
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException(Constantes.ERROR_LECTURA_FICHERO_CONFIGURACION, ex);
            }
        }

        /// <summary>
        /// Escribe los parámetros al fichero XML indicado.
        /// </summary>
        /// <param name="fichero">Fichero de configuración XML</param>
        public override void escribir(string fichero)
        {
            try
            {
                base.escribir(fichero);
                XmlWriter xml = EscribirXml.AbrirFicheroParametros(fichero);
                EscribirXml.InicioElemento(xml, CActualizarDatos.NodoRaiz);
                EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoEntrada, Entrada);
                EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoSalida, Salida);
                EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoEstructuraEntrada, EstructuraEntrada);
                EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoEstructuraSalida, EstructuraSalida);
                // Configuración
                EscribirXml.InicioElemento(xml, CActualizarDatos.NodoConfiguracion);
                EscribirXml.InicioElemento(xml, CActualizarDatos.NodoTablas);
                for (int indiceTabla = 0; indiceTabla < ListaTablasDatos.Count; indiceTabla++)
                {
                    EscribirXml.InicioElemento(xml, CActualizarDatos.NodoTabla);
                    EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoTablasDatos, ListaTablasDatos[indiceTabla]);
                    EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoTablasEstructuras, ListaTablasEstructuras[indiceTabla]);

                    // Campos clave de la tabla
                    string camposClaveTabla = string.Empty;
                    foreach(string campo in ListaTablasCamposClaveTabla[indiceTabla])
                    {
                        camposClaveTabla += campo + CActualizarDatos.SeparadorListado;
                    }
                    if (!string.Empty.Equals(camposClaveTabla))
                        camposClaveTabla = camposClaveTabla.Substring(0, camposClaveTabla.Length - 1);
                    EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoTablasCamposClaveTabla, camposClaveTabla);

                    // Campos clave de la entrada
                    string camposClaveMaestro = string.Empty;
                    foreach (string campo in ListaTablasCamposClaveMaestro[indiceTabla])
                    {
                        camposClaveMaestro += campo + CActualizarDatos.SeparadorListado;
                    }
                    if (!string.Empty.Equals(camposClaveMaestro))
                        camposClaveMaestro = camposClaveMaestro.Substring(0, camposClaveMaestro.Length - 1);
                    EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoTablasCamposClaveMaestro, camposClaveMaestro);

                    // Campos fuente de la tabla
                    string camposFuenteTabla = string.Empty;
                    foreach (string campo in ListaTablasCamposFuenteTabla[indiceTabla])
                    {
                        camposFuenteTabla += campo + CActualizarDatos.SeparadorListado;
                    }
                    if (!string.Empty.Equals(camposFuenteTabla))
                        camposFuenteTabla = camposFuenteTabla.Substring(0, camposFuenteTabla.Length - 1);
                    EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoTablasCamposFuenteTabla, camposFuenteTabla);

                    // Campos destino de la entrada
                    string camposDestinoMaestro = string.Empty;
                    foreach (string campo in ListaTablasCamposDestinoMaestro[indiceTabla])
                    {
                        camposDestinoMaestro += campo + CActualizarDatos.SeparadorListado;
                    }
                    if (!string.Empty.Equals(camposDestinoMaestro))
                        camposDestinoMaestro = camposDestinoMaestro.Substring(0, camposDestinoMaestro.Length - 1);
                    EscribirXml.EscribeNodo(xml, CActualizarDatos.NodoTablasCamposDestinoMaestro, camposDestinoMaestro);

                    EscribirXml.FinElemento(xml);
                }
                EscribirXml.FinElemento(xml);
                EscribirXml.FinElemento(xml);
                EscribirXml.FinElemento(xml);
                EscribirXml.Flush(xml);
                EscribirXml.Close(xml);
            }
            catch (Exception ex)
            {
                throw new ApplicationException(Constantes.ERROR_ESCRITURA_FICHERO_CONFIGURACION, ex);
            }
        }
    }
}
 